package work.pcdd.validator.common.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import work.pcdd.validator.entity.JsonResult;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;

/**
 * @author 1907263405@qq.com
 * @date 2021/5/15 19:27
 */
/**
 * 統一异常处理
 */

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    // @Validated @Valid 注解异常信息捕获 BindException
    @ExceptionHandler(value = BindException.class)
    public JsonResult bindException(BindException exception) {
        BindingResult result = exception.getBindingResult();
        StringBuilder errorMsg = new StringBuilder();
        List<FieldError> fieldErrors = result.getFieldErrors();
        fieldErrors.forEach(error -> {
            log.error("field: " + error.getField() + ", msg:" + error.getDefaultMessage());
            errorMsg.append(error.getDefaultMessage()).append("! ");
        });
        return JsonResult.error(errorMsg.toString());
    }

    // @Validated @Valid 注解异常信息捕获 MethodArgumentNotValidException
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public JsonResult methodArgumentNotValidException(MethodArgumentNotValidException exception) {
        BindingResult result = exception.getBindingResult();
        StringBuilder errorMsg = new StringBuilder();
        List<FieldError> fieldErrors = result.getFieldErrors();
        fieldErrors.forEach(error -> {
            log.error("field: " + error.getField() + ", msg:" + error.getDefaultMessage());
            errorMsg.append(error.getDefaultMessage()).append("! ");
        });
        return JsonResult.error(errorMsg.toString());
    }

    // @Validated @Valid 注解异常信息捕获 ConstraintViolationException
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public JsonResult constraintViolationException(ConstraintViolationException exception) {
        StringBuilder errorMsg = new StringBuilder();
        Set<ConstraintViolation<?>> violations = exception.getConstraintViolations();
        violations.forEach(error -> {
            log.error("field: " + error.getPropertyPath() + ", msg:" + error.getMessage());
            errorMsg.append(error.getMessageTemplate()).append("! ");
        });
        return JsonResult.error(errorMsg.toString());
    }

    // 处理运行时异常
    @ExceptionHandler(RuntimeException.class)
    public JsonResult doHandleRuntimeException(RuntimeException e) {
        log.error(e.getMessage(), e);
        e.printStackTrace();
        return JsonResult.fail(e.getMessage());
    }
}

